package com.summer.NIO;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class ChannelCase1 {
	
	public static void main(String[] args) throws IOException {
//		RandomAccessFileTest test = new RandomAccessFileTest();
//		LargeMappedFilesTest test = new LargeMappedFilesTest();
//		test.doTest();
		FileWriteThread.doTest();
	}
	
	public static class RandomAccessFileTest{
		public void doTest() throws IOException{
			RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");  
	        for (int i = 0; i < 10; i++) {  
	            //写入基本类型double数据  
	            rf.writeDouble(i * 1.414);  
	        }  
	        rf.close();  
	        rf = new RandomAccessFile("rtest.dat", "rw");  
	        //直接将文件指针移到第5个double数据后面  
	        rf.seek(5 * 8);  
	        //覆盖第6个double数据  
	        rf.writeDouble(47.0001);  
	        rf.close();  
	        rf = new RandomAccessFile("rtest.dat", "r");  
	        for (int i = 0; i < 10; i++) {  
	            System.out.println("Value " + i + ": " + rf.readDouble());  
	        }  
	        rf.close();
		}
	}
	
	public static class LargeMappedFilesTest{
		private static final int length = 0x8000000; // 128 Mb  
		public void doTest() throws IOException{
			// 为了以可读可写的方式打开文件，这里使用RandomAccessFile来创建文件。  
	        @SuppressWarnings("resource")
			FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel();  
	        //注意，文件通道的可读可写要建立在文件流本身可读写的基础之上  
	        MappedByteBuffer outBuffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);  
	        //写128M的内容  
	        for (int i = 0; i < length; i++) {  
	            outBuffer.put((byte) 'x');  
	        }  
	        System.out.println("Finished writing");  
	        //读取文件中间6个字节内容  
	        for (int i = length / 2; i < length / 2 + 6; i++) {  
	            System.out.print((char) outBuffer.get(i));  
	        }  
	        fc.close(); 
		}
	}
	
	// 利用线程在文件的指定位置写入指定数据  
    public static class FileWriteThread extends Thread{  
        private int skip;  
        private byte[] content;  
          
        public FileWriteThread(int skip,byte[] content){  
            this.skip = skip;  
            this.content = content;  
        }  
        
        public static void doTest() throws IOException{
    		// 预分配文件所占的磁盘空间，磁盘中会创建一个指定大小的文件  
            RandomAccessFile raf = new RandomAccessFile("D://abc.txt", "rw");  
            raf.setLength(1024*1024); // 预分配 1M 的文件空间  
            raf.close();  
              
            // 所要写入的文件内容  
            String s1 = "第一个字符串";  
            String s2 = "第二个字符串";  
            String s3 = "第三个字符串";  
            String s4 = "第四个字符串";  
            String s5 = "第五个字符串";  
              
            // 利用多线程同时写入一个文件  
            new FileWriteThread(1024*1,s1.getBytes()).start(); // 从文件的1024字节之后开始写入数据  
            new FileWriteThread(1024*2,s2.getBytes()).start(); // 从文件的2048字节之后开始写入数据  
            new FileWriteThread(1024*3,s3.getBytes()).start(); // 从文件的3072字节之后开始写入数据  
            new FileWriteThread(1024*4,s4.getBytes()).start(); // 从文件的4096字节之后开始写入数据  
            new FileWriteThread(1024*5,s5.getBytes()).start(); // 从文件的5120字节之后开始写入数据  
    	}
        
        public void run(){  
            RandomAccessFile raf = null;  
            try {  
                raf = new RandomAccessFile("D://abc.txt", "rw");  
                raf.seek(skip);  
                raf.write(content);  
            } catch ( IOException e) {  
                e.printStackTrace();  
            } finally {  
                try {  
                    raf.close();  
                } catch (Exception e) {  
                }  
            }  
        }
    }
	
}
